package net.skycloud.f5.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import net.skycloud.f5.validation.ADD;
import net.skycloud.f5.validation.UPDATE;
import org.hibernate.validator.constraints.NotBlank;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.Set;
import java.util.UUID;

/**
 * Created by ayang on 2017/7/28.
 */

@Entity
@Table(name = "NAP_DEVICE_CREDENTIAL", indexes = {
        @Index(name = "IDX_DEVICE_CREDENTIAL", columnList = "ID, NAME, TYPE")
})
@ApiModel(value = "Device Credential", description = "设备连接凭证")
public class DeviceCredential {

    @Id
    @Column(name = "ID")
    @org.hibernate.annotations.Type(type = "org.hibernate.type.PostgresUUIDType")
    @ApiModelProperty(value = "凭证ID", required = false, example = "876C2203-7472-44E8-9EB6-13CF372D326C")
    private UUID id;

    @Column(name = "NAME", length = 50, unique = true)
    @NotBlank(groups = {ADD.class}, message = "error.not_blank")
    @Size(min = 1, max = 50, groups = {ADD.class, UPDATE.class}, message = "error.size")
    @ApiModelProperty(value = "凭证名,长度1~50", required = true, example = "cred-1")
    private String name;

    @Column(name = "TYPE", length = 50)
    @Enumerated(EnumType.STRING)
    @ApiModelProperty(
            value = "凭证类型", required = true, allowableValues = "USERNAME_PASSWORD", example = "USERNAME_PASSWORD")
    private CredentialType type;

    @Column(name = "VALUE", columnDefinition = "TEXT")
    @NotBlank(groups = {ADD.class}, message = "error.not_blank")
    @Size(min = 1, groups = {ADD.class, UPDATE.class}, message = "error.size")
    @ApiModelProperty(
            value = "凭证内容", required = true, example = "{\"username\":\"foo\",\"password\":\"bar\"}")
    private String data;

    @Column(name = "DESCRIPTION", length = 255)
    @Size(min = 0, max = 255, groups = {ADD.class, UPDATE.class}, message = "error.size")
    @ApiModelProperty(value = "详细说明,长度0~255", required = false, example = "description to add")
    private String description;

    @ManyToMany(mappedBy = "credentials", fetch = FetchType.LAZY)
    @JsonIgnore
    @ApiModelProperty(hidden = true)
    private Set<Device> devices;

    @Column(name = "CREATED_AT")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Column(name = "UPDATED_AT")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public CredentialType getType() {
        return type;
    }

    public void setType(CredentialType type) {
        this.type = type;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Device> getDevices() {
        return devices;
    }

    public void setDevices(Set<Device> devices) {
        this.devices = devices;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    @Override
    public String toString() {
        return "DeviceCredential{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", type=" + type +
                ", value='" + data + '\'' +
                ", description='" + description + '\'' +
                ", createAt='" + createdAt + '\'' +
                ", updateAt='" + updatedAt + '\'' +
                '}';
    }

    @PreRemove
    private void detachWithDevice() {
        for (Device dev : devices) {
            dev.getCredentials().remove(this);
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DeviceCredential)) {
            return false;
        }
        DeviceCredential target = (DeviceCredential) obj;
        if (target.getId() != null
                && this.id != null) {
            return this.id.equals(target.getId());
        } else {
            return this == obj;
        }
    }
}
